﻿using System;
using System.Linq;
using System.Web.UI.WebControls;
using Delivery.AlipayClass;
using System.Xml;
using System.Text;

namespace ECommerce.Administration.Controls
{
	public partial class OrderDetail : AdminBaseUsercontrol
	{
		private Service.IOrderService _OrderService;
		private Service.IProductService _ProductService;
		private Service.IShippingMethodService _ShippingMethodService;
		private Service.IPaymentMethodService _PaymentMethodService;

		private Data.Entity.Order _Order;

		public int OrderID
		{
			get
			{
				return CommonHelper.QueryStringInt("orderid");
			}
		}

		protected void Page_Load(object sender, EventArgs e)
		{
			if(OrderID > 0)
			{
				LabelOrderDetailTitle.Text = GetLocalResourceString("Admin.OrderDetail.Title");

				ButtonDelete.Text = GetLocalResourceString("Admin.DeleteButtonText");
				ButtonCancelOrder.Text = GetLocalResourceString("Admin.ButtonCacelOrder.Text");
				ButtonMarkAsPaid.Text = GetLocalResourceString("Admin.ButtonMarkAsPaid.Text");
				ButtonSetTrackingNumber.Text = GetLocalResourceString("Admin.ButtonSetTrackingNumber.Text");
				ButtonSetAsShipped.Text = GetLocalResourceString("Admin.ButtonSetAsShipped.Text");
				ButtonSetAsDelivered.Text = GetLocalResourceString("Admin.ButtonSetAsDelivered.Text");

				TabPanelOrderInfo.HeaderText = GetLocalResourceString("Admin.OrderDetail.OrderInfoTabHeaderText");
				TabPanelOrderNote.HeaderText = GetLocalResourceString("Admin.OrderDetail.OrderNoteHeaderText");
				TabPanelProducts.HeaderText = GetLocalResourceString("Admin.OrderDetail.ProductsHeaderText");
				TabPanelShippingInfo.HeaderText = GetLocalResourceString("Admin.OrderDetail.ShippingInfoHeaderText");

				BindOrderData();
			}
		}

		protected void gvOrderNotes_RowDataBound(object sender, GridViewRowEventArgs e)
		{
			if(e.Row.RowType == DataControlRowType.Header)
			{
				e.Row.Cells[0].Text = GetLocalResourceString("Admin.OrderDetail.OrderNote.CreatedDate.HeaderText");
				e.Row.Cells[1].Text = GetLocalResourceString("Admin.OrderDetail.OrderNote.Note.HeaderText");
			}
		}

		protected void gvOrderProduct_RowDataBound(object sender, GridViewRowEventArgs e)
		{
			if(e.Row.RowType == DataControlRowType.Header)
			{
				e.Row.Cells[1].Text = GetLocalResourceString("Admin.OrderDetail.OrderProduct.ProductName.HeadText");
				e.Row.Cells[2].Text = GetLocalResourceString("Admin.OrderDetail.OrderProduct.ListPrice.HeadText");
				e.Row.Cells[3].Text = GetLocalResourceString("Admin.OrderDetail.OrderProduct.Quantity.HeadText");
				e.Row.Cells[4].Text = GetLocalResourceString("Admin.OrderDetail.OrderProduct.SumPrice.HeadText");
			}
			else if(e.Row.DataItem != null)
			{
				var productID = gvOrderProduct.DataKeys[e.Row.RowIndex]["ProductID"] as int?;
				var productName = gvOrderProduct.DataKeys[e.Row.RowIndex]["ProductName"] as string;
				var HyperLinkProductImg = e.Row.FindControl("HyperLinkProductImg") as HyperLink;
				var HyperLinkProductName = e.Row.FindControl("HyperLinkProductName") as HyperLink;

				var url = "~/Administration/EditProduct.aspx?productid=" + productID.Value.ToString();
				HyperLinkProductImg.ImageUrl = "~/Administration/AdminPictureHandler.ashx?picturesize=75&productid=" + productID.Value.ToString();
				HyperLinkProductImg.NavigateUrl = url;
				HyperLinkProductImg.ToolTip = productName;
				HyperLinkProductName.Text = productName;
				HyperLinkProductName.NavigateUrl = url;
			}
		}

		protected void ButtonDelete_Click(object sender, EventArgs e)
		{
			if(OrderID > 0)
			{
				if(_OrderService == null)
				{
					_OrderService = new Service.OrderService();
				}

				if(_OrderService.DeleteOrder(OrderID) > 0)
				{
					Server.Transfer("~/Administration/OrderManage.aspx");
				}
			}
		}

		protected void ButtonCancelOrder_Click(object sender, EventArgs e)
		{
		}

		protected void ButtonMarkAsPaid_Click(object sender, EventArgs e)
		{
			if(_Order != null)
			{
				if(_OrderService == null)
				{
					_OrderService = new Service.OrderService();
				}

				_Order.PaymentStatusID = (int)Data.Entity.PaymentStatuses.Payed;
				_Order.PaidDate = DateTime.Now;

				if(_OrderService.UpdateOrder(_Order) > 0)
				{
					BindOrderData();
				}
			}
		}

		protected void ButtonSetTrackingNumber_Click(object sender, EventArgs e)
		{
			if(_Order != null)
			{
				if(_OrderService == null)
				{
					_OrderService = new Service.OrderService();
				}

				_Order.TrackingNumber = TextTrackingNumber.Text.Trim();

				if(_OrderService.UpdateOrder(_Order) > 0)
				{
					BindOrderData();
				}
			}
		}

		protected void ButtonSetAsShipped_Click(object sender, EventArgs e)
		{
			if(_Order != null)
			{
				if(_Order.PaymentMethodName.Equals("支付宝"))
				{
					AliSendGoods();

					BindOrderData();
				}
				else
				{
					if(_OrderService == null)
					{
						_OrderService = new Service.OrderService();
					}

					_Order.ShippedDate = DateTime.Now;
					_Order.ShippingStatusID = (int)Data.Entity.ShippingStatuses.Shipped;

					if(_OrderService.UpdateOrder(_Order) > 0)
					{
						BindOrderData();
					}
				}
			}
		}

		protected void ButtonSetAsDelivered_Click(object sender, EventArgs e)
		{
			if(_Order != null)
			{
				if(_Order.PaymentMethodName.Equals("支付宝"))
				{
					AliSendGoods();
				}
				else
				{
					if(_OrderService == null)
					{
						_OrderService = new Service.OrderService();
					}

					_Order.DeliveryDate = DateTime.Now;

					if(_OrderService.UpdateOrder(_Order) > 0)
					{
						BindOrderData();
					}
				}
			}
		}

		private void AliSendGoods()
		{
			//******************************************请求处理**********************************************//
			///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的///////////////////////////
			string partner = "2088302091633148";                                     //合作身份者ID
			string key = "rs8e8p90hciw3rlwqtvxjhqfu3s0f6kz";                         //安全检验码
			string input_charset = "utf-8";                                          //字符编码格式 目前支持 gbk 或 utf-8
			string sign_type = "MD5";                                                //加密方式 不需修改

			////////////////////////////////////////////////////////////////////////////////////////////////////

			//必填参数
			string trade_no = _Order.PurchaseOrderNumber;                      //支付宝交易号。它是登陆支付宝网站在交易管理中查询得到，一般以8位日期开头的纯数字（如：20100419XXXXXXXXXX） 
			string logistics_name = TextShippingCompany.Text.Trim();          //物流公司名称
			string invoice_no = TextTrackingNumber.Text.Trim();                  //物流发货单号
			string transport_type = _Order.ShippingMethod; //物流发货时的运输类型，三个值可选：POST（平邮）、EXPRESS（快递）、EMS（EMS）

			//选填参数
			string seller_ip = string.Empty;                                          //卖家本地电脑IP地址

			/////////////////////////////////////////////////////////////////////////////////////////////////////

			//构造请求函数
			AlipayService aliService = new AlipayService(
				partner,
				trade_no,
				logistics_name,
				invoice_no,
				transport_type,
				seller_ip,
				key,
				input_charset,
				sign_type);

			//GET方式传递
			string url = aliService.Create_url();

			//////////////////////////////////////////远程XML解析////////////////////////////////////////////////
			//远程XML解析,是点击“发货”后，支付宝立刻反馈回来的信息。称作为：XML返回
			//注意：远程解析XML出错，与IIS服务器配置有关
			XmlTextReader Reader = new XmlTextReader(url);
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(Reader);

			//******************************************返回处理**********************************************//
			////////////////////////////////////////////////////////////////////////////////////////////////////
			//解析XML，获取XML返回的数据，如：请求处理是否成功、商家网站唯一订单号、支付宝交易号、发货时间等
			string nodeIs_success = xmlDoc.SelectSingleNode("/alipay/is_success").InnerText;
			string nodeOut_trade_no = string.Empty;
			string nodeTrade_no = string.Empty;
			string nodeTrade_status = string.Empty;
			string nodeLast_modified_time = string.Empty;
			string nodeError = string.Empty;

			if(nodeIs_success == "T")
			{
				nodeOut_trade_no = xmlDoc.SelectSingleNode("/alipay/response/tradeBase/out_trade_no").InnerText;
				nodeTrade_no = xmlDoc.SelectSingleNode("/alipay/request").ChildNodes[2].InnerText;
				nodeTrade_status = xmlDoc.SelectSingleNode("/alipay/response/tradeBase/trade_status").InnerText;
				nodeLast_modified_time = xmlDoc.SelectSingleNode("/alipay/response/tradeBase/last_modified_time").InnerText;
			}
			else
			{
				nodeError = xmlDoc.SelectSingleNode("/alipay/error").InnerText;
			}

			//打印页面
			StringBuilder sbHtml = new StringBuilder();
			sbHtml.Append("<table align=center width=350 cellpadding=5 cellspacing=0>");
			sbHtml.Append("<tr><td align=center class=font_title colspan=2>XML返回</td></tr>");
			sbHtml.Append("<tr><td class=font_content align=right>请求处理是否成功：</td><td class=font_content align=left>" + nodeIs_success + "</td></tr>");
			if(nodeIs_success == "T")
			{
				sbHtml.Append("<tr><td class=font_content align=right>商户网站订单号：</td><td class=font_content align=left>" + nodeOut_trade_no + "</td></tr>");
				sbHtml.Append("<tr><td class=font_content align=right>支付宝交易号：</td><td class=font_content align=left>" + nodeTrade_no + "</td></tr>");
				sbHtml.Append("<tr><td class=font_content align=right>交易状态：</td><td class=font_content align=left>" + nodeTrade_status + "</td></tr>");
				sbHtml.Append("<tr><td class=font_content align=right>发货时间等：</td><td class=font_content align=left>" + nodeLast_modified_time + "</td></tr>");
			}
			else
			{
				sbHtml.Append("<tr><td class=font_content align=right>错误：</td><td class=font_content align=left>" + nodeError + "</td></tr>");
			}
			sbHtml.Append("</table>");

			LabelDeliveryMsg.Text = sbHtml.ToString();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			//请在此处编写商户发货成功后的业务逻辑程序代码，以便把商户网站里的该笔订单与支付宝的订单信息同步。

			//set the order status is WAIT_BUYER_CONFIRM_GOODS
			SetOrderStatus_WAIT_BUYER_CONFIRM_GOODS();

			///////////////////////////////////////////////////////////////////////////////////////////////////
		}

		private void SetOrderStatus_WAIT_BUYER_CONFIRM_GOODS()
		{
			if(OrderID > 0)
			{
				if(_OrderService == null)
				{
					_OrderService = new Service.OrderService();
				}

				if(_Order == null)
				{
					_Order = _OrderService.GetTheOrderByOrderID(OrderID);
				}

				var theNewOrderStatus = _OrderService.GetTheOrderStatusByStatusName("WAIT_BUYER_CONFIRM_GOODS");

				_Order.OrderStatusID = theNewOrderStatus.OrderStatusID;
				_Order.ShippingCompany = TextShippingCompany.Text.Trim();
				_Order.TrackingNumber = TextTrackingNumber.Text.Trim();
				_Order.ShippedDate = DateTime.Now;
				_Order.ShippingStatusID = (int)Data.Entity.ShippingStatuses.Shipped;

				if(_OrderService.UpdateOrder(_Order) > 0)
				{
					var theOrderNote = new Data.Entity.OrderNote();
					var theOrderStatus = _OrderService.GetAllOrderStatus().Where(exp => exp.OrderStatusID == _Order.OrderStatusID).FirstOrDefault();

					theOrderNote.CreatedOn = DateTime.Now;
					theOrderNote.DisplayToUser = true;
					theOrderNote.Note = GetLocalResourceString(theOrderStatus.Name);
					theOrderNote.OrderID = _Order.OrderID;

					_OrderService.CreateNewOrderNote(theOrderNote);
				}
			}
		}

		private void BindOrderData()
		{
			if(OrderID <= 0)
			{
				return;
			}

			if(_OrderService == null)
			{
				_OrderService = new Service.OrderService();
			}

			if(_Order == null)
			{
				_Order = _OrderService.GetTheOrderByOrderID(OrderID);
			}

			decimal sumProductProce = 0;
			BindOrderProduct(out sumProductProce);

			BindOrderNotes();

			this.LabelCreatedOn.Text = _Order.CreatedOn.ToString();
			this.LabelCustomer.Text = System.Web.Security.Membership.GetUser(_Order.UserID).UserName;
			this.LabelOrderNumber.Text = _Order.OrderNumber;
			this.LabelOrderProductCost.Text = sumProductProce.ToString("c2");
			this.LabelProductTotalPrice.Text = sumProductProce.ToString("c2");

			this.LabelOrderTotal.Text = _Order.OrderTotal.Value.ToString("c2");
			this.LabelPaymentMethodName.Text = _Order.PaymentMethodName;
			this.LabelShippingAddress1.Text = _Order.ShippingAddress1;
			this.LabelShippingCost.Text = GetShippingCost(_Order.ShippingStateProvinceID.Value, _Order.ShippingMethodID.Value).ToString("c2");
			this.LabelShippingEmail.Text = _Order.ShippingEmail;
			this.LabelShippingFaxNumber.Text = _Order.ShippingFaxNumber;
			this.LabelShippingFullName.Text = _Order.ShippingFirstName + _Order.ShippingLastName;
			this.LabelShippingMethod.Text = _Order.ShippingMethod;
			this.LabelShippingMobileNumber.Text = _Order.ShippingMobileNumber;
			this.LabelShippingPhoneNumber.Text = _Order.ShippingPhoneNumber;
			this.LabelShippingStateProvinceCity.Text = _Order.ShippingCountry + "/" + _Order.ShippingStateProvince + "/" + _Order.ShippingCity;
			this.LabelShippingZipPostalCode.Text = _Order.ShippingZipPostalCode;
			this.LabelOrderRemark.Text = _Order.Remark;

			var thePaymentStatus = GetPaymentStatus(_Order.PaymentStatusID.Value);
			ButtonMarkAsPaid.Visible = thePaymentStatus.Name.ToLower().Equals("pending");
			this.LabelPaymentStatus.Text = thePaymentStatus.Name;

			var theOrderStatus = GetOrderStatus();
			this.LabelOrderStatus.Text = GetLocalResourceString(theOrderStatus.Name);

			if(_Order.ShippedDate.HasValue)
			{
				this.LabelShippedDate.Text = _Order.ShippedDate.Value.ToString();
				ButtonSetAsShipped.Visible = false;
			}
			else
			{
				ButtonSetAsShipped.Visible = true;
			}
			if(_Order.DeliveryDate.HasValue)
			{
				this.LabelDeliveryDate.Text = _Order.DeliveryDate.Value.ToString();
				ButtonSetAsDelivered.Visible = false;
			}
			else
			{
				ButtonSetAsDelivered.Visible = true;
			}

			if(string.IsNullOrEmpty(_Order.TrackingNumber))
			{
				TextTrackingNumber.Visible = true;
				ButtonSetTrackingNumber.Visible = true;
			}
			else
			{
				ButtonSetTrackingNumber.Visible = false;
				TextTrackingNumber.Visible = false;

				LabelTrackingNumber.Text = _Order.TrackingNumber;
			}

			divPurchaseOrderNumber.Visible = _Order.PaymentMethodName.Equals("支付宝");
			ButtonSetTrackingNumber.Visible = !_Order.PaymentMethodName.Equals("支付宝");

			if(!string.IsNullOrEmpty(_Order.PurchaseOrderNumber))
			{
				LabelPurchaseOrderNumber.Text = _Order.PurchaseOrderNumber;
				TextPurchaseOrderNumber.Visible = false;
			}
			else
			{
				TextPurchaseOrderNumber.Visible = true;
			}
		}

		private void BindOrderNotes()
		{
			if(OrderID > 0)
			{
				if(_OrderService == null)
				{
					_OrderService = new Service.OrderService();
				}

				gvOrderNotes.DataSource = _OrderService.GetOrderNoteByOrder(OrderID);
				gvOrderNotes.DataBind();
			}
		}

		private void BindOrderProduct(out decimal sumProductPrice)
		{
			if(_OrderService == null)
			{
				_OrderService = new Service.OrderService();
			}

			if(_ProductService == null)
			{
				_ProductService = new Service.ProductService();
			}

			var orderProductMappings = (from op in _OrderService.GetOrderProductMappingByOrder(OrderID)
										join prod in _ProductService.GetProductsByLanguage(_Order.UserLanguageID) on op.ProductID equals prod.ProductID
										select new
										{
											ProductID = prod.ProductID,
											ProductName = prod.Name,
											ListPrice = prod.ListPrice,
											Quantity = op.Quantity,
											SumPrice = prod.ListPrice * op.Quantity
										});

			sumProductPrice = 0;

			if(orderProductMappings != null && orderProductMappings.Count() > 0)
			{
				//var lstOrderProductMappings = orderProductMappings.ToList();

				//if (lstOrderProductMappings.Count > 0)
				//{
				gvOrderProduct.DataSource = orderProductMappings;
				gvOrderProduct.DataBind();

				sumProductPrice = orderProductMappings.Sum(e => e.SumPrice.Value);
				//}
			}
		}

		private decimal GetShippingCost(int stateProvinceID, int shippingMethodID)
		{
			if(stateProvinceID > 0 && shippingMethodID > 0)
			{
				if(_ShippingMethodService == null)
				{
					_ShippingMethodService = new Service.ShippingMethodService();
				}
				var shipping = _ShippingMethodService.GetShippingByStateAndProvinceByProvince(stateProvinceID);
				decimal cost = decimal.Zero;
				if(shipping != null)
				{
					cost = (from s in _ShippingMethodService.GetShippingByStateAndProvinceByProvince(stateProvinceID)
							where s.ShippingMethodID.Equals(shippingMethodID)
							select s.TransportCosts).FirstOrDefault();
				}

				return cost;
			}
			else
			{
				return decimal.Zero;
			}
		}

		private Data.Entity.PaymentStatus GetPaymentStatus(int paymentStatusID)
		{
			if(paymentStatusID <= 0)
			{
				return null;
			}

			if(_PaymentMethodService == null)
			{
				_PaymentMethodService = new Service.PaymentMethodService();
			}

			return _PaymentMethodService.GetAllPaymentStatus().Where(exp => exp.PaymentStatusID == paymentStatusID).FirstOrDefault();
		}

		private Data.Entity.OrderStatus GetOrderStatus()
		{
			if(_Order == null)
			{
				return null;
			}

			if(_OrderService == null)
			{
				_OrderService = new Service.OrderService();
			}

			return _OrderService.GetAllOrderStatus().Where(exp => exp.OrderStatusID == _Order.OrderStatusID).FirstOrDefault();
		}
	}
}